import {
  reactive,
  type Reactive,
  type Ref,
  shallowRef,
  ref,
  onMounted,
  onBeforeUnmount,
  watch
} from 'vue';
import {
  SelectedState,
  EditState,
  Options,
  Column,
  DataSource,
  Props,
  ErrorsState
} from './type';

import Global from './global'
import Cache from "./cache"

export default class extends Global {
  constructor(options: Options) {
    super(options)

    const mousedownHandel = (e: any) => this.listenTableMousedown(e);
    onMounted(() => {
      document.addEventListener('mousedown', mousedownHandel);
    });
    onBeforeUnmount(() => {
      this.historyRecords?.destory();
      document.removeEventListener('mousedown', mousedownHandel);
    });
   }

  selectedState: Reactive<SelectedState> = reactive<SelectedState>({});

  editState: Reactive<EditState> = reactive<EditState>({});

  errorState: Reactive<ErrorsState> = reactive<ErrorsState>({});

  // 是否聚标在此表格
  currentView: boolean = false;

  getMinStartY() {
    return Math.min(
      this.selectedState.startY ?? 0,
      this.selectedState.endY ?? 0,
    );
  }
  getMaxEndY() {
    return Math.max(
      this.selectedState.startY ?? 0,
      this.selectedState.endY ?? 0,
    );
  }
  getMinStartX() {
    return Math.min(
      this.selectedState.startX ?? 0,
      this.selectedState.endX ?? 0,
    );
  }
  getMaxEndX() {
    return Math.max(
      this.selectedState.startX ?? 0,
      this.selectedState.endX ?? 0,
    );
  }

  private listenTableMousedown(e) {
    let node = e.target;
    while (node && node !== document.body) {
      if (node === this.table.value) {
        this.currentView = true;
        return false;
      }
      node = node.parentElement;
    }
    this.currentView = false;
  }

  private historyRecords = new Cache({
    beforeRedoUndo: () => this.currentView ? Promise.resolve() : Promise.reject(),
    redoUndoCallback: ({ columns, dataSource, selectedState }: {columns: Column[], dataSource: DataSource, selectedState: SelectedState}) => {
      this.columns.value = columns;
      this.dataSource.value.splice(0, this.dataSource.value.length, ...dataSource);
      Object.assign(this.selectedState, selectedState);
      this.editState.editX = this.editState.editY = this.editState.status = undefined;
    }
  });

  addHistoryRecord (options: any = {}){
    if (!this.props.openUndo || this.props.disabled === true || this.props.readonly === true) return;
    
    this.historyRecords.save({
      columns: [...this.columns.value],
      dataSource: [...this.dataSource.value],
      selectedState: this.selectedState,
      ...options
    })
  }
  emptyHistoryRecord(){
    return this.historyRecords.getLength() === 0
  }
  can_undo(){
    return this.historyRecords.can_undo()
  }
  undo(){
    this.historyRecords?.undo();
  }
  can_redo(){
    return this.historyRecords.can_redo()
  }
  redo(){
    this.historyRecords?.redo();
  }
}
